package cn.iocoder.yudao.module.system.service.a_articleLog;

import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.a_article.vo.ArticleReqVO;
import cn.iocoder.yudao.module.system.controller.admin.a_manuscriptLog.vo.ArticleComparisonReqVO;
import cn.iocoder.yudao.module.system.controller.admin.a_manuscriptLog.vo.ArticleLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.a_article.ArticleLogDO;
import cn.iocoder.yudao.module.system.dal.mysql.a_article.ArticleLogMapper;
import cn.iocoder.yudao.module.system.util.a_gaojian.Diff_match_patch;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.trs.hybase.client.*;
import com.trs.hybase.client.params.SearchParams;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lxj
 */
@Service
@Validated
public class ArticleLogServiceImpl implements ArticleLogService {

    @Resource
    private ArticleLogMapper articleLogMapper;

    /**
     * 稿件日志表名
     */
    @Value("${hybase.dbname.articleLog}")
    private String articleLog;

    /**
     * 文稿表名
     */
    @Value("${hybase.dbname.article}")
    private String article;

    @Override
    public void insertArticleLog(TRSConnection conn, ArticleReqVO articleReqVO) {
        //创建记录对象
        List<TRSInputRecord> recordList = new ArrayList<>();
        TRSInputRecord record = new TRSInputRecord();
        //添加字段
        try {
            record.addColumn("id", IdUtil.fastSimpleUUID());
            record.addColumn("title", articleReqVO.getTitle());
            record.addColumn("content", articleReqVO.getContent());
            record.addColumn("category", articleReqVO.getCategory());
            record.addColumn("version", articleReqVO.getVersion());
            record.addColumn("create_user_id", articleReqVO.getCreateUserId());
            record.addColumn("create_user_name", articleReqVO.getCreateUserName());
            record.addColumn("create_time", articleReqVO.getLastModificationTime());
            record.addColumn("coverUrl", articleReqVO.getCoverUrl());
            record.addColumn("relevanceId", articleReqVO.getId());
            recordList.add(record);
            //执行插入记录（暂时在内存中）
            conn.executeInsert(articleLog, recordList);
        } catch (TRSException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Boolean findExistByRelevanceId(TRSConnection conn, String relevanceId) {
        //设置返回结果字段
        TRSResultSet resultSet;
        String whereStr = "relevanceId:" + relevanceId;
        try {
            resultSet = conn.executeSelect(articleLog, whereStr, 0, 1, new SearchParams());
            if (resultSet != null) {
                if (resultSet.getNumFound() > 0) {
                    return true;
                }
            }
        } catch (TRSException e) {
            System.out.println("ErrorCode:" + e.getErrorCode());
            System.out.println("ErrorString:" + e.getErrorString());
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        return false;
    }

    @Override
    public PageResult<ArticleLogDO> findPageByRelevanceId(ArticleLogPageReqVO pageReqVO) {
        return articleLogMapper.page(pageReqVO);
    }

    @Override
    public Map<Integer, ArticleLogDO> versionComparison(ArticleComparisonReqVO reqVO) {
        Map<Integer, ArticleLogDO> resultMap = new HashMap<>();

        // 获取旧版本和新版本的文章内容
        ArticleLogDO oldArticleReqVO = getArticleContent(reqVO, reqVO.getVersion() - 1);
        ArticleLogDO newArticleReqVO = getArticleContent(reqVO, reqVO.getVersion());

        // 使用正则匹配和替换图片标签，提取并替换旧版本和新版本中的图片
        Map<String, String> oldImgMap = extractAndReplaceImages(oldArticleReqVO);
        Map<String, String> newImgMap = extractAndReplaceImages(newArticleReqVO);

        // 比较两版本的文章内容，并生成HTML格式的差异对比
        String diffResult = Diff_match_patch.getHtmlDiffString(oldArticleReqVO.getContent(), newArticleReqVO.getContent())
                .replace("&lt;", "<").replace("&gt;", ">");

        // 处理对比结果中的图片标签，替换为相应的占位符
        diffResult = strHandle(diffResult, newImgMap, oldImgMap);

        // 更新旧文章内容（用于显示对比）
        oldArticleReqVO.setContent(strHandle(oldArticleReqVO.getContent(), oldImgMap, newImgMap));

        // 更新新文章内容，已包含差异对比
        newArticleReqVO.setContent(diffResult);

        // 根据版本号填充返回的结果 Map，确保每个版本都有相应的文章内容
        if (reqVO.getVersion() == 1) {
            resultMap.put(1, oldArticleReqVO); // 如果是版本1，只返回旧版本
        } else {
            resultMap.put(reqVO.getVersion() - 1, oldArticleReqVO); // 否则返回相应版本的旧版本
        }
        resultMap.put(reqVO.getVersion(), newArticleReqVO); // 返回新版本的文章内容
        return resultMap;
    }

    // 获取文章内容（包括查找数据库，默认获取版本号对应的内容）
    private ArticleLogDO getArticleContent(ArticleComparisonReqVO reqVO, int version) {
        // 如果版本号无效（如小于等于0），直接返回一个空的 ArticleLogDO 对象
        if (version <= 0) {
            return new ArticleLogDO();
        }
        // 否则根据版本号从数据库或其他存储源获取对应的文章内容
        return findContentByDBNameAndId(reqVO.getRelevanceId(), version);
    }

    // 提取并替换文章中的图片标签
    private Map<String, String> extractAndReplaceImages(ArticleLogDO article) {
        String content = article.getContent();  // 获取文章的原始内容
        Pattern pattern = Pattern.compile("<img\\s+.*?>"); // 定义正则表达式匹配图片标签
        Matcher matcher = pattern.matcher(content); // 使用 Matcher 对象匹配图片标签
        Map<String, String> imgMap = new HashMap<>();  // 用于存储图片标签与占位符的映射关系
        int index = 0; // 图片标签占位符的索引

        // 遍历所有匹配的图片标签
        while (matcher.find()) {
            String imgTag = matcher.group(); // 获取匹配的图片标签
            String placeholder = "img-" + index++;  // 为每个图片标签生成一个唯一的占位符
            content = content.replace(imgTag, placeholder); // 替换文章内容中的图片标签为占位符
            imgMap.put(placeholder, imgTag); // 将占位符与图片标签进行映射
        }

        article.setContent(content); // 更新文章内容，保存占位符替代后的内容
        return imgMap; // 返回图片标签和占位符的映射关系
    }

    private String strHandle(String str, Map<String, String> map1, Map<String, String> map2) {
        for (String key : map1.keySet()) {
            str = str.replace(key, map1.get(key));
            if (str.contains(key)) {
                str = str.replace(key, "");
            }
        }
        for (String key : map2.keySet()) {
            str = str.replace(key, "");
        }
        return str;
    }

    private ArticleLogDO findContentByDBNameAndId(String relevanceId, Integer version) {
        return articleLogMapper.selectOne(new QueryWrapper<ArticleLogDO>()
                .eq("relevance_id", relevanceId)
                .eq("version", version));
    }
}
